'use strict';

const util = require('util')
const validation = require('./validation')
const uuid = require('uuid')

module.exports = {
    /**
     * Pick request body
     * @param  {Array} fileds
     * @return {Object}
     */
    pick(...fileds) {
        return this.validator(this.request.body, fileds)
    },

    translationId() {
        return uuid()
    },

    /**
     * Validation
     * @param  {Object} data
     * @param  {Array} fileds
     * @return {Object}
     */
    validator(data, fileds) {
        const result = {}

        for (const item of fileds) {
            if (!item) return this.throw(500, 'KoaPickerFieldError')

            // string item param
            if (typeof item === 'string') {
                const val = data[item]
                val !== undefined && (result[item] = val)
                continue
            }

            // object item param
            if (!util.isObject(item) && !item.key) {
                return this.throw(500, 'KoaPcikerKeyRequried')
            }

            const key = item.key
            let value = data[key]
            if (value === undefined) {
                if (item.required) {
                    if (typeof item.required === 'string') {
                        return this.throw(400, item.required)
                    }

                    return this.throw(400, 'KoaRequestError')
                }
            }

            if (item.trim) {
                value = String(value).trim()
            }

            const expects = item.expects

            if (expects) {
                // string expect
                if (util.isString(expects)) {
                    const expect = validation[expects]

                    if (!expect) {
                        return this.throw(500, 'KoaValidationNotFound')
                    }

                    if (!item.required && util.isNullOrUndefined(value)) {
                        continue
                    }

                    if (!expect.exec(value)) {
                        return this.throw(400, `${expect.message}`)
                    }
                }
                // array expect
                // if ( util.isArray(expects) ) {
                //     for ( let v=0; v<expects.length; v++ ) {
                //     }
                // }
            }

            value !== undefined && (result[key] = value)
        }

        return result
    },


    getToken() {
        return this.get('token') ||
            this.query.token ||
            this.cookies.get('token')
    },

    setToken(token) {
        this.cookies.set('token', token)
    },

    locale() {
        return this.get('Accept-Language')
    },

    /**
     * Set request success response body
     * @param  {Object} data
     * @return {NULL}
     */
    send(data) {
        this.body = {
            success: true,
            data,
            errors: []
        }
    },


    ok() {
        this.send('ok')
    },


    render(code, data) {
        // @todo
        if (code > 400) {

        }
    },

    /**
     * Set request error response
     * @param  {Number} status
     * @param  {String} code
     * @param  {String} message
     * @param  {String} info
     * @return {NULL}
     */
    err(status = 500, code = 'InternalServerError', message = '', info = '') {

        this.status = status

        this.body = {
            success: false,
            data: {},
            errors: [{
                code,
                message,
                info
            }]
        }
    },

    /**
     * Set request errors response
     * @param  {Number} status
     * @param  {Array} errors
     * @return {NULL}
     */
    errs(status = 500, errors) {

        this.status = status

        this.body = {
            success: false,
            data: {},
            errors
        }
    },
}